import asyncio
import playwright.async_api
from playwright.async_api import async_playwright
import pipeline as pl
import os
import sys
from settings import ORIGIN_UP_HOME_PAGE_LINK, ORIGIN_PERSONAL_VIDEO_LINK, OUTPUT_UP_HOMEPAGE_DETAIL
from settings import ORIGIN_DATA_PATH, OUTPUT_DATA_PATH
import openpyxl
from openpyxl import Workbook
import re
from filter import State


print(os.getcwd())


def load_file():
        wb = openpyxl.load_workbook(ORIGIN_DATA_PATH + ORIGIN_UP_HOME_PAGE_LINK)
        ws = wb.active
        num = 0
        up_video_homepage_link = []
        for line in ws:
            link = str(line[0].value)
            up_video_homepage_link.append(link + '/video')
            num += 1
        return up_video_homepage_link

async def extract_current_page_href(page:playwright.async_api.Page, uid, target):
    items = []
    p = await page.locator('.length').all_text_contents()
    q = await page.query_selector_all('.cover')
    print('fetch ', len(q) / 2, ' video link')
    num = int(len(q) / 2)
    for i in range(num):
        link = await q[i].get_attribute('href')
        video_time = p[i]
        item = {}
        item['link'] = 'https:' + link
        item['uid'] = uid
        item['video_time'] = video_time
        item['target_video_num'] = target
        items.append(item)
    return items

async def extract_total_video(context:playwright.async_api.BrowserContext, link):
    content = []
    print('link: ', link)
    page = await context.new_page()
    uid = re.findall('\d+', link)[0]

    try:
        # following: `document`, `stylesheet`, `image`, `media`, `font`, `script`, `texttrack`, `xhr`, `fetch`,
        # `eventsource`, `websocket`, `manifest`, `other`.
        await page.route("**/*", lambda route: route.abort()
        if route.request.resource_type == "image"
        else route.continue_())
        await page.goto(link, wait_until="networkidle") # domcontentloaded networkidle
        await asyncio.sleep(1)
        video_num = await page.locator('#submit-video-type-filter span').all_text_contents()
        target_video_num = 0
        if len(video_num) > 0:
            target_video_num = int(video_num[0])

        print('target video num = ', target_video_num)
        count = 0
        while count < target_video_num:
            await page.wait_for_selector('css=.small-item', timeout=5000)
            next_content = await extract_current_page_href(page, uid, target_video_num)
            content.extend(next_content)
            count = len(content)
            if count == target_video_num:
                break
            # await page.wait_for_selector('css=.next', state="attached", timeout=5000)  # 2 secs
            # await asyncio.sleep(3)
            await page.click('.be-pager-next', timeout=10000) # 0.5 secs
        if len(content) > 0:
            print('total video num :' + str(len(content)))
            pl.add_links(ORIGIN_PERSONAL_VIDEO_LINK, content)
            State.get_instance().update_and_save(uid, ok=True)
        else:
            print('no content')
    except playwright.async_api.TimeoutError as e:
        print(e)
        await page.close()
    else:
        #print('unexpected error')
        await page.close()

async def fetch(context):
    urls = load_file()
    page = await context.new_page()
    try:
        for l in urls:
            uid = re.findall('\d+', l)[0]
            filter = State.get_instance()
            filter.update_state()
            if filter.check_has_loaded(uid):
                continue
            await extract_total_video(context, l)

    except playwright.async_api.TimeoutError as e:
        print(e)
    else:
        print('over')
        await page.close()

async def bilibili() -> None:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context(storage_state='auth.json')
        await fetch(context=context)
        await context.close()
        await browser.close()

def main(argv):
    loop = asyncio.get_event_loop()
    loop.run_until_complete(bilibili())


if __name__ == "__main__":
    main(sys.argv)

